#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <ctime>
#include <cstdlib>
#include "lockguard.hpp"
#include "blockqueue.hpp"
#include "task.hpp"


using namespace std;

int add(int x, int y)
{
    return x + y;
}

void *consumer(void *arg)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)arg;
    while (true)
    {
        // 消费（获取）任务
        Task task;
        bq->Pop(&task);
        // 处理任务
        cout << "consumer[" << pthread_self() % 10000 << "]: " << task._x << " + " << task._y << " = " << task() << endl;
         //sleep(1);
    }
    return nullptr;
}

void *producer(void *arg)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)arg;

    while (true)
    {
        // 制作任务
        int x = rand() % 10;
        usleep(rand() % 1000);
        int y = rand() % 10;
        Task task(x, y, add);
        // 生产任务
        bq->Push(task);
        cout << "producer[" << pthread_self() % 10000 << "]: " << task._x << " + " << task._y << " = ?" << endl;
        //sleep(1);
    }
    return nullptr;
}

int main()
{
    srand((unsigned int)time(nullptr));
    BlockQueue<Task> *bq = new BlockQueue<Task>;
    pthread_t c[2], p[2];
    pthread_create(c, nullptr, consumer, (void *)bq);
    usleep(100);
    pthread_create(p, nullptr, producer, (void *)bq);
    usleep(100);
    pthread_create(c + 1, nullptr, consumer, (void *)bq);
    usleep(100);
    pthread_create(p + 1, nullptr, producer, (void *)bq);

    pthread_join(c[0], nullptr);
    pthread_join(p[0], nullptr);
    pthread_join(c[1], nullptr);
    pthread_join(p[1], nullptr);

    delete bq;
    
    return 0;
}